﻿using System.Collections.Generic;
using System.IO;
using System.Text;

namespace Folks.UI
{
	internal sealed class FolksParserWriter : StringWriter
	{
		#region Fields
		private Dictionary<string, string> hiddenFields;
		private FolksParserStep previousStep = FolksParserStep.Generic;
		private string currentId = string.Empty;

		private StringBuilder containerResponse = new StringBuilder();
		private string contentToWatch = string.Empty;
		private bool insideContainer = false;
		#endregion

		#region Properties
		internal Dictionary<string, string> HiddenFields
		{
			get
			{
				if (hiddenFields == null)
					hiddenFields = new Dictionary<string, string>();
				return hiddenFields;
			}
		}

		internal string ContainerResponse
		{
			get { return containerResponse.ToString(); }
		}


		public string ContainerToWatch
		{
			get { return contentToWatch; }
			set { contentToWatch = value; }
		}
		#endregion

		#region Overriden Methods
		public override void Write(string value)
		{
			base.Write(value);
			VerifyHiddenFieldStep(value);
			if (insideContainer)
				containerResponse.Append(value);
		}

		public override void Write(char value)
		{
			base.Write(value);
			if (insideContainer)
				containerResponse.Append(value);
		}

		public override void WriteLine(string value)
		{
			base.WriteLine(value);
			if (!string.IsNullOrEmpty(ContainerToWatch))
				VerifyContainer(value);
		}

		#endregion

		#region Methods

		private void VerifyHiddenFieldStep(string value)
		{
			switch (previousStep)
			{
				case FolksParserStep.HiddenFieldId:
					if (string.IsNullOrEmpty(currentId))
						currentId = value;
					break;
				case FolksParserStep.HiddenFieldValue:
					if (!HiddenFields.ContainsKey(currentId))
					{
						HiddenFields.Add(currentId, value);
						currentId = string.Empty;
						previousStep = FolksParserStep.Generic;
					}
					break;
			}

			switch (value)
			{
				case "<input type=\"hidden\" name=\"":
					previousStep = FolksParserStep.HiddenFieldName;
					break;
				case "\" id=\"":
					previousStep = FolksParserStep.HiddenFieldId;
					break;
				case "\" value=\"":
					previousStep = FolksParserStep.HiddenFieldValue;
					break;
			}
		}

		private void VerifyContainer(string value)
		{
            string prefix = FolksContainer.ContainerPrefixBegin
                    + ContainerToWatch + FolksContainer.ContainerPrefixEnd;

            string sufix = FolksContainer.ContainerSufixBegin
                    + ContainerToWatch + FolksContainer.ContainerSufixEnd;

            if (!insideContainer)
            {
                if(value == prefix) 
                    insideContainer = true;
            }
            else if (value == sufix)
                insideContainer = false;
            else
                containerResponse.Append(value);
		}

		#endregion

		private enum FolksParserStep
		{
			Generic, HiddenFieldName, HiddenFieldId, HiddenFieldValue
		}
	}
}
